package com.burgstaller.aGTD.utils;

import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

import com.burgstaller.aGTD.AGtdContentProvider;
import com.burgstaller.aGTD.ContextList;
import com.burgstaller.aGTD.R;
import com.burgstaller.aGTD.R.id;
import com.burgstaller.aGTD.R.layout;
import com.burgstaller.aGTD.R.string;
import com.burgstaller.provider.AGtd;

public abstract class AbstractListBase extends ListActivity {

	public static final int DELETE_ID = Menu.FIRST;
	public static final int INSERT_ID = Menu.FIRST + 1;
	public static final int EDIT_ID = INSERT_ID + 1;
	protected Cursor m_cursor;

	public AbstractListBase() {
		super();
	}

	protected abstract String[] getProjection();

	protected int provideContentViewResourceId() {
		return R.layout.main;
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		int contentViewResId = provideContentViewResourceId();
		if (contentViewResId > 0) {
			setContentView(contentViewResId);
		}

		Intent intent = getIntent();
		if (intent.getData() == null) {
			intent.setData(AGtd.Contexts.CONTENT_URI);
		}
		String viewTitle = intent.getStringExtra("viewtitle");
		if (viewTitle != null) {
			setTitle(viewTitle);
		}

		m_cursor = managedQuery(getIntent().getData(), getProjection(),
				getSqlWhere(), null);

		ListAdapter adapter = provideListAdapter();
		setListAdapter(adapter);

		//
		//		// Use an existing ListAdapter that will map an array
		//		// of strings to TextViews
		//        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
		//				android.R.layout.simple_list_item_1, 
		//				AGtd.Contexts.SAMPLE_DATA);
		//		setListAdapter(adapter);

		//		AutoCompleteTextView quickFilter = (AutoCompleteTextView) findViewById(R.id.quickfilter);
		//		quickFilter.setAdapter(adapter);
	}


	@Override
	protected void onDestroy() {
		if (m_cursor != null) {
			managedCommitUpdates(m_cursor);
			AGtdContentProvider.popCursor(m_cursor);
			m_cursor = null;
		}
		super.onDestroy();
	}
	
	protected String getSqlWhere() {
		return null;
	}

	protected ListAdapter provideListAdapter() {
		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
				R.layout.list, m_cursor,
				new String[] { AGtd.CommonColumns.TITLE },
				new int[] { R.id.text1 });
		return adapter;
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Log.d(AGtd.LOG_TAG, "data url: " + getIntent().getData());
		Uri url = Uri.withAppendedPath(getListItemBaseURI(), "" + id);
		Intent targetIntent = new Intent(getClickAction(), url);

		Log.d(AGtd.LOG_TAG, "list click url:" + url);
		String title = getTargetViewTitle(v);
		if (title != null) {
			targetIntent.putExtra("viewtitle", title);
		}

		startActivity(targetIntent);
	}

	/** 
	 * defines the action which should be exectued when the user clicks
	 * with the center key on a list item.
	 * @return the action code / string.
	 */
	protected abstract String getClickAction();

	/**
	 * this method will return the uri for a list item of this view. By default
	 * it will allow adding the id of an item to reference the leaf object.
	 * 
	 * @return the content uri of the list of managed items.
	 */
	protected abstract Uri getListItemBaseURI();

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		// This is our one standard application action -- inserting a
		// new note into the list.
		menu.add(0, INSERT_ID, R.string.menu_insert).setShortcut('3', 'a');
		menu.add(0, EDIT_ID, R.string.menu_edit).setShortcut('5', 'e');

		// Generate any additional actions that can be performed on the
		// overall list.  In a normal install, there are no additional
		// actions found here, but this allows other applications to extend
		// our menu with their own actions.
		Intent intent = new Intent(null, getIntent().getData());
		intent.addCategory(Intent.ALTERNATIVE_CATEGORY);
		menu.addIntentOptions(Menu.ALTERNATIVE, 0, new ComponentName(this,
				ContextList.class), null, intent, 0, null);

		return true;
	}

	protected void addAdditionalMenus(Menu menu, Uri uri) {
		// do nothing
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);

		final boolean haveItems = m_cursor.count() > 0;

		// If there are any notes in the list (which implies that one of
		// them is selected), then we need to generate the actions that
		// can be performed on the current selection.  This will be a combination
		// of our own specific actions along with any extensions that can be
		// found.
		if (haveItems) {
			// This is the selected item.
			Uri uri = Uri.withAppendedPath(getListItemBaseURI(), ""
					+ getSelectedItemId());
			addAdditionalMenus(menu, uri);

			// Build menu...  always starts with the EDIT action...
			Intent[] specifics = new Intent[1];
			specifics[0] = new Intent(Intent.EDIT_ACTION, uri);
			Menu.Item[] items = new Menu.Item[1];

			// ... is followed by whatever other actions are available...
			Intent intent = new Intent(null, uri);
			intent.addCategory(Intent.SELECTED_ALTERNATIVE_CATEGORY);
			menu.addIntentOptions(Menu.SELECTED_ALTERNATIVE, 0, null,
					specifics, intent, Menu.NONE, items);

			// ... and ends with the delete command.
			menu.add(Menu.SELECTED_ALTERNATIVE, DELETE_ID,
							R.string.menu_delete).setShortcut('2', 'd');
			//			menu.addSeparator(Menu.SELECTED_ALTERNATIVE, 0);

			// Give a shortcut to the edit action.
			if (items[0] != null) {
				items[0].setShortcut('1', 'e');
			}
		} else {
			menu.removeGroup(Menu.SELECTED_ALTERNATIVE);
		}

		// Make sure the delete action is disabled if there are no items.
		menu.setItemShown(DELETE_ID, haveItems);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(Menu.Item item) {
		switch (item.getId()) {
		case DELETE_ID:
			deleteItem();
			return true;
		case INSERT_ID:
			insertItem();
			return true;
		case EDIT_ID:
			editItem();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	protected void deleteItem() {
		m_cursor.moveTo(getSelectedItemPosition());
		m_cursor.deleteRow();
	}

	protected final void insertItem() {
		// Launch activity to insert a new item
		startActivity(new Intent(Intent.INSERT_ACTION, getIntent().getData()));
	}

	private void editItem() {
		startActivity(new Intent(Intent.EDIT_ACTION, getEditURI()));
	}

	private Uri getEditURI() {
		return Uri.withAppendedPath(getIntent().getData(), ""
				+ getSelectedItemId());
	}

	/** this method returns the view title of the target activity. 
	 * per default this method returns a null string which will then 
	 * let the target activity decide which title it wants.
	 * @param v 
	 */
	protected String getTargetViewTitle(View v) {
		return null;
	}
}